/**
 * Project Reactor
 */


#include "EventLoop.h"

/**
 * EventLoop implementation
 */
void display(map<int,TcpConnection> &map){
    for(auto it = map.begin() ; it != map.end() ; it++){
        cout<<it->first<<":"<<it->second.getSock().getFd()<<endl;
    }
}

/**
 * @param accept
 */
EventLoop::EventLoop(Acceptor & acceptor) 
:m_acceptor(acceptor),m_evtList(new struct epoll_event[1024]()),m_isLooping(true)
{

}

EventLoop::~EventLoop() {
    if(m_evtList){
        delete[] m_evtList;
        m_evtList = NULL;   
    }
}

void EventLoop::loop() {
    createEpollFd();
    int listenfd = m_acceptor.getSock().getFd();
    addEpollReadFd(listenfd);
    while(m_isLooping){
        int readyNum = m_epoll_wait();
        for(int i = 0 ; i< readyNum ; i++){
            if(m_evtList[i].data.fd == listenfd){
                handleNewConnection();
                display(m_connMap);
            }else{
                int connfd = m_evtList[i].data.fd;
                handleMessage(connfd);
            }
        }
    }
}

void EventLoop::handleNewConnection() {
    int connfd = m_acceptor.m_accept();
    TcpConnection conn(connfd);
    m_connMap.emplace(connfd,std::move(conn));
    addEpollReadFd(connfd);
    cout<<"建立新连接，连接fd = "<<connfd<<endl;
    cout<<conn.streamToString()<<endl;
}

/**
 * @param fd
 */

void EventLoop::handleMessage(int fd) {
    cout<<"处理消息"<<endl;
    auto it = m_connMap.find(fd); // 获取迭代器
    if (it == m_connMap.end()) {
        return; // 键不存在时直接返回
    }
    
    // 通过迭代器操作现有元素（避免拷贝和构造检查）
    TcpConnection& conn = it->second; // 引用而非拷贝！
    conn.receive();
    conn.send("hello baby\n");
}


/**
 * @return int
 */
void EventLoop::createEpollFd() {
    m_epfd = epoll_create(MAX_EVTLIST_SIZE);
}

/**
 * @param fd
 */
void EventLoop::addEpollReadFd(int fd) {
    struct epoll_event evt,ep[MAX_EVTLIST_SIZE];
    evt.events = EPOLLIN;
    evt.data.fd = fd;
    int ret = epoll_ctl(m_epfd,EPOLL_CTL_ADD,fd,&evt);
    if(ret<0){
        perror("epoll_ctl");
        return;
    }
    cout<<"添加成功"<<endl;
}

/**
 * @param fd
 */
void EventLoop::delEpollReadFd(int fd) {
    struct epoll_event evt;
    evt.data.fd = fd;
    int ret = epoll_ctl(m_epfd,EPOLL_CTL_DEL,fd,&evt);
    if(ret <0){
        perror("epoll_del");
        return;
    }
}

int EventLoop::m_epoll_wait() {
    int readyNum = epoll_wait(m_epfd,m_evtList,MAX_EVTLIST_SIZE,-1);
    return readyNum;
}



void EventLoop::unloop() {
    m_isLooping = false;
}

void EventLoop::waitEpollFd() {

}